package org.hawk.gwt.ppc.reflect;

import java.lang.reflect.Modifier;
import java.util.List;

import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Constructor;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Field;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Method;
import org.hawk.gwt.ppc.reflect.lang.ClassDelegate;
/**
 * Represents java modifiers that can be returned by 
 * {@link ClassDelegate#getModifiers()}, {@link Constructor#getModifiers()},
 * {@link Method#getModifiers()} and {@link Field#getModifiers()} methods
 * of the reflection API. 
 * 
 * @author alex.bereznevatiy@gmail.com
 */
public enum JavaModifier {
	PUBLIC(Modifier.PUBLIC),
	PROTECTED(Modifier.PROTECTED),
	PRIVATE(Modifier.PRIVATE),
	DEFAULT(0),
	STATIC(Modifier.STATIC),
	FINAL(Modifier.FINAL),
	VOLATILE(Modifier.VOLATILE),
	SYNCHRONIZED(Modifier.SYNCHRONIZED),
	TRANSIENT(Modifier.TRANSIENT),
	NATIVE(Modifier.NATIVE),
	ABSTRACT(Modifier.ABSTRACT),
	STRICTFP(Modifier.STRICT);
	
	private int modifier;
	
	private JavaModifier(int modifier){
		this.modifier = modifier;
	}
	
	static JavaModifier resolve(String token) {
		if(!token.toLowerCase().equals(token)){
			return null;
		}
		try {
			return valueOf(token.toUpperCase());
		}
		catch(IllegalArgumentException ex){
			return null;
		}
	}

	static void checkForDefaultVisibility(List<JavaModifier> modifiers, 
			boolean isIterface, int type) {
		if(isIterface){
			checkForDefaultVisibility(modifiers,type);
			return;
		}
		for(JavaModifier mod : modifiers){
			if(mod.equals(PUBLIC)||mod.equals(PRIVATE)||
				mod.equals(PROTECTED)||mod.equals(DEFAULT)){
				return;
			}
		}
		modifiers.add(DEFAULT);
	}

	private static void checkForDefaultVisibility(
			List<JavaModifier> modifiers,int type) {
		if(type!=MetadataProcessor.TYPE_FIELD&&
			type!=MetadataProcessor.TYPE_METHOD){
			return;
		}
		if(type==MetadataProcessor.TYPE_FIELD){
			if(!modifiers.contains(STATIC))
				modifiers.add(STATIC);
			if(!modifiers.contains(FINAL))
				modifiers.add(FINAL);
		}
		if(!modifiers.contains(PUBLIC)){
			modifiers.add(PUBLIC);
		}
	}

	static int getMask(List<JavaModifier> modifiers) {
		int mask = 0;
		for(JavaModifier mod : modifiers){
			mask |= mod.modifier;
		}
		return mask;
	}
}
